package com.supercube.sport.yoga.controller;

import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.supercube.common.controller.BaseController;
import com.supercube.common.utils.DateUtils;
import com.supercube.common.utils.StringUtils;
import com.supercube.sport.yoga.bo.BatchSigned;
import com.supercube.sport.yoga.bo.BookingCourseBO;
import com.supercube.sport.yoga.bo.ClassSingedBo;
import com.supercube.sport.yoga.bo.MemberSignedBo;
import com.supercube.sport.yoga.dao.BookingCourseMapper;
import com.supercube.sport.yoga.dao.CourseBasicInfoMapper;
import com.supercube.sport.yoga.dao.CoursesSupportedCardMapper;
import com.supercube.sport.yoga.domain.BookingCourseDTO;
import com.supercube.sport.yoga.domain.CoursesSupportedCardDTO;
import com.supercube.sport.yoga.service.BookingCourseService;
import com.supercube.sport.yoga.service.ClassTableInfo;
import com.supercube.sport.yoga.service.SiteInfoService;
import com.supercube.sport.yoga.utils.ResultInfo;
import com.supercube.sport.yoga.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/bookingCourse")
@Api(tags = "预约课程管理")
public class BookingCourseController extends BaseController {

    @Autowired
    private CourseBasicInfoMapper courseBasicInfoMapper;

    @Autowired
    private BookingCourseService bookingCourseService;

    @Autowired
    private ClassTableInfoController classTableInfoController;

    @Autowired
    private ClassTableInfo classTableInfo;

    @Autowired
    private SiteInfoService siteInfoService;

    @Autowired
    private CoursesSupportedCardMapper coursesSupportedCardMapper;

    @Autowired
    private BookingCourseMapper bookingCourseMapper;

    @ApiOperation(value = "保存预约课程信息", notes = "保存预约课程信息")
    @PostMapping("/saveBookingCourse")
    public ResultInfo saveBookingCourse(@RequestBody BookingCourseDTO dto) {
        if (checkBookingCourse(dto)) {
            return ResultInfo.failed("参数有误");
        }
        String memberId = dto.getMemberId();
        String classId = dto.getClassId();
        Integer alreadyAppointment = bookingCourseMapper.isAlreadyAppointment(classId, memberId);
        if (alreadyAppointment > 0) {
            return ResultInfo.failed("已经预约成功，不可重复预约");
        }
        List<CoursesSupportedCardDTO> supportedCourses = coursesSupportedCardMapper.selectCoursesSupportedCardByCardId(dto.getCardId());
        Map<String, String> supportedCourseMap = new HashMap<>();
        supportedCourses.forEach(sc -> {
            supportedCourseMap.put(sc.getCourseId(),sc.getCostPerClassPersonGroup());
        });
        ClassTableInfoVO vo = classTableInfo.queryClassTableInfoById(dto.getClassId());
        /*if ("3".equals(classTableInfoVO.getType())) { // 私教课
            String venueId = classTableInfoVO.getVenueId();
            List<SiteInfoVO> siteInfoVOList = siteInfoService.querySiteInfoByVenueId(venueId)
                    .stream()
                    .filter(siteInfoVO -> !"1".equals(siteInfoVO.getUsePurpose()))
                    .collect(Collectors.toList());

            for (SiteInfoVO siteInfoVO : siteInfoVOList) {
                List<BookingCourseVO> bookingCourseVOList = bookingCourseService.queryBookingCourseBySiteId(siteInfoVO.getId(), dto.getClassId());
                int count = 0;//计数-
                for (BookingCourseVO bookingCourseVO : bookingCourseVOList) {
                    String appointmentTime = bookingCourseVO.getStartTime();

                    Date nowTimeUp = DateUtils.formatStrDateHHmm(dto.getStartTime());
                    Date nowTimeDown = DateUtils.formatStrDateHHmm(DateUtils.getDate(
                            nowTimeUp,
                            "HH:mm",
                            Integer.parseInt(classTableInfoVO.getCourseDuration()),
                            Calendar.MINUTE));
                    Date startTime = DateUtils.formatStrDateHHmm(appointmentTime);
                    Date endTime = DateUtils.formatStrDateHHmm(DateUtils.getDate(
                            DateUtils.formatStrDateHHmm(appointmentTime),
                            "HH:mm",
                            Integer.parseInt(classTableInfoVO.getCourseDuration()),
                            Calendar.MINUTE));
                    if (DateUtils.isEffectiveDate(nowTimeUp, startTime, endTime) || DateUtils.isEffectiveDate(nowTimeDown, startTime, endTime)) {
                        count++;
                    }
                }
                if (count < siteInfoVO.getAccommodationNumber()) {
                    dto.setSiteId(siteInfoVO.getId());
                    String endTime = DateUtils.getDate(DateUtils.formatStrDateHHmm(dto.getStartTime()), "HH:mm", 60, Calendar.MINUTE);
                    dto.setEndTime(endTime);
                }
            }
        }*/
        String endTime = dto.getEndTime();
        if (StringUtils.isEmpty(endTime)) {
            String s = dto.getStartTime();
            if (!"3".equals(vo.getType())) { // 私教课
                s = vo.getOpeningTimeHour() + ":" + vo.getOpeningTime();
            }
            endTime = DateUtils.getDate(DateUtils.formatStrDateHHmm(s), "HH:mm",
                    Integer.parseInt(StringUtils.getDefault(vo.getCourseDuration(), "60")), Calendar.MINUTE);
        }
        dto.setEndTime(endTime);
        dto.setId(randomUUID());
        dto.setStatus("2"); //2:电话预约（场馆帮助预约）；
        dto.setAppointmentUser(getUsername());
        String siteId = dto.getSiteId();
        if (StringUtils.isEmpty(siteId)) {
            siteId = vo.getSiteId();
        }
        String sellPrice = dto.getSellPrice();
        if (StringUtils.isEmpty(sellPrice)) {
            sellPrice = supportedCourseMap.get(vo.getCourseId());
        }
        dto.setSellPrice(sellPrice);
        dto.setSiteId(siteId);
        dto.setAppointmentTime(getCurrentTime());
        int num = bookingCourseService.save(dto);
        if (num == 0) {
            return ResultInfo.failed("预约失败");
        }
        return ResultInfo.success("预约成功");
    }

    private boolean checkBookingCourse(BookingCourseDTO dto) {
        if (StringUtils.isEmpty(dto.getClassId()) || StringUtils.isEmpty(dto.getMemberId()) || dto.getBookingNum() <= 0) {
            return true;
        }
        return false;
    }

    @ApiOperation(value = "私教是不是满足预约", notes = "私教是不是满足预约")
    @PostMapping("/isSatisfyBookingPersonalCourse")
    public ResultInfo isSatisfyBookingPersonalCourse(@RequestBody BookingCourseDTO dto) {

        return ResultInfo.failed(" ");
    }

    @ApiOperation(value = "取消预约课程信息", notes = "取消预约课程信息")
    @PostMapping("/cancel")
    public ResultInfo cancelBookingCourse(@RequestBody BookingCourseDTO dto) {
        // 1:会员预约；2:电话预约（场馆帮助预约）；3:签到；4:会员取消预约；5：电话取消预约（场馆帮助取消预约）;6:无效预约；
        BookingCourseVO vo = bookingCourseService.queryBookingCourseById(dto.getId());
        String status = vo.getStatus();
        if (Lists.newArrayList("1", "2").contains(status)) {
            dto = new BookingCourseDTO();
            dto.setId(vo.getId());
            dto.setAppointmentTime(DateUtils.getDateTime());
            dto.setAppointmentUser(getUsername());
            dto.setStatus("5");
            dto.setZb(dto.getZb());
            bookingCourseService.update(dto);
            return ResultInfo.success("取消成功");
        } else if (Lists.newArrayList("3").contains(status)) {
            return ResultInfo.failed("已签到，不可取消");
        } else {
            return ResultInfo.failed("已取消，无需重复取消");
        }
    }

    @ApiOperation(value = "查询预约课程信息", notes = "查询预约课程信息")
    @PostMapping("/queryBookingCourseById")
    public ResultInfo queryBookingCourseById(@RequestParam("id") String id) {
        BookingCourseVO vo = bookingCourseService.queryBookingCourseById(id);
        return ResultInfo.success(vo);
    }

    @ApiOperation(value = "私教预约时，查出当前已预约状态的课时信息", notes = "私教预约时，查出当前已预约状态的课时信息")
    @PostMapping("/queryPrivateAppointmentClass")
    public ResultInfo queryPrivateAppointmentClass(@RequestBody BookingCourseBO bo) {
        List<ClassTableInfoVO> vos = classTableInfo.queryPrivateAppointmentClass(bo);
        return ResultInfo.success(vos);
    }

    @ApiOperation(value = "查询所有签到记录", notes = "查询所有签到记录")
    @PostMapping("/getSignedRecord")
    public ResultInfo getSignedRecord(@RequestBody SignedRecordVo vo) {
        List<SignedRecordVo> list = bookingCourseService.getSignedRecord(vo);
        PageInfo<SignedRecordVo> pageInfo = new PageInfo<>(list);
        return ResultInfo.success(pageInfo);
    }

    @ApiOperation(value = "会员签到查询场馆", notes = "会员签到查询场馆")
    @ApiImplicitParam(name = "memberId", value = "会员id", dataType = "string", paramType = "query")
    @PostMapping("/getMemberSigned")
    public ResultInfo getMemberSigned(@RequestBody Map<String, String> map) {
        String memberId = map.get("memberId");
        if (StringUtils.isBlank(memberId)) {
            return ResultInfo.failed("请选择会员");
        }
        List<Map<String, String>> list = bookingCourseService.queryVenue(memberId);
        return ResultInfo.success(list);
    }

    @ApiOperation(value = "会员预约根据场馆查询会员卡种类", notes = "会员预约根据场馆查询会员卡种类")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "venuesId", value = "场馆id", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "memberId", value = "会员id", dataType = "string", paramType = "query")
    }
    )
    @PostMapping("/getMemberCardAppointment")
    public ResultInfo getMemberCardAppointment(@RequestBody Map<String, String> map) {
        String venuesId = map.get("venuesId");
        String memberId = map.get("memberId");
//        if(StringUtils.isBlank(venuesId)){
//            return ResultInfo.failed("请选择场馆");
//        }
        if (StringUtils.isBlank(memberId)) {
            return ResultInfo.failed("请选择会员");
        }
        List<MemberCardBindVo> list = bookingCourseService.getMemberCardAppointment(map);
        return ResultInfo.success(list);
    }

    @ApiOperation(value = "会员签到根据场馆查询会员卡种类", notes = "会员签到根据场馆查询会员卡种类")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "venuesId", value = "场馆id", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "memberId", value = "会员id", dataType = "string", paramType = "query")}
    )
    @PostMapping("/getMemberCard")
    public ResultInfo getMemberCard(@RequestBody Map<String, String> map) {
        String venuesId = map.get("venuesId");
        String memberId = map.get("memberId");
//        if(StringUtils.isBlank(venuesId)){
//            return ResultInfo.failed("请选择场馆");
//        }
        if (StringUtils.isBlank(memberId)) {
            return ResultInfo.failed("请选择会员");
        }
        List<MemberCardBindVo> list = bookingCourseService.getMemberCard(map);
        return ResultInfo.success(list);
    }

    @ApiOperation(value = "模糊查询课程信息", notes = "模糊查询课程信息")
    @PostMapping("/getCourseBaseInfo")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "courseName", value = "课程名称", dataType = "string", paramType = "query"),
    }
    )
    public ResultInfo getCourseBaseInfo(@RequestBody Map<String, String> map) {
        List<CourseBasicInfoVO> list = bookingCourseService.getCourseBaseInfo(map);
        return ResultInfo.success(list);
    }


    @ApiOperation(value = "查询预约课时信息", notes = "查询预约课时信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "memberId", value = "会员id", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "signStatus", value = "签到状态：1=未签到，2=已签到", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "courseId", value = "课程id", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "courseType", value = "课程类别", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "startDate", value = "预约开始,2020-08-16 16:19:39", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "endDate", value = "预约结束,2020-08-31 16:19:39", dataType = "string", paramType = "query"),
    }
    )
    @PostMapping("/getClassInfo")
    public ResultInfo getClassInfo(@RequestBody ClassSingedBo bo) {
        List<ClassInfoVo> list = bookingCourseService.getClassInfo(bo);
        return ResultInfo.success(list);
    }

    @ApiOperation(value = "会员签到确认", notes = "会员签到确认")
    @PostMapping("/saveMemberSigned")
    public ResultInfo saveMemberSigned(@RequestBody MemberSignedBo bo) {
        if (CollectionUtils.isEmpty(bo.getBookingCourseId())) {
            return ResultInfo.failed("请选择预约课时");
        }
        bookingCourseService.saveMemberSigned(bo);
        return ResultInfo.success("签到成功");
    }

    @ApiOperation(value = "批量会员签到确认", notes = "批量会员签到确认")
    @PostMapping("/batchSaveMemberSigned")
    public ResultInfo batchSaveMemberSigned(@RequestBody List<BatchSigned> list) {
        if (CollectionUtils.isEmpty(list)) {
            return ResultInfo.failed("请选择预约课时");
        }
        bookingCourseService.batchSaveMemberSigned(list);
        return ResultInfo.success("签到成功");
    }

    @ApiOperation(value = "根据课表id获取该课表的可以预约时间列表", notes = "根据课表id获取该课表的可以预约时间列表")
    @PostMapping("/queryAppointmentTimeList")
    public ResultInfo queryAppointmentTimeList(String classId) {
        ClassTableInfoVO vo = classTableInfo.queryClassTableInfoById(classId);
        String startTime = vo.getOpeningTimeHour() + ":" + vo.getOpeningTime();
        String endTime = vo.getEndTime();
        long doubleDateSubtract = DateUtils.getDoubleDateSubtract(startTime, endTime);
        List<String> appointmentTimeList = new ArrayList<>();
        appointmentTimeList.add(startTime);
        for (int i = 0; i < doubleDateSubtract / 30; i++) {
            // TODO 私教时间差设置，默认30分钟 String timeBetweenClasses = vo.getTimeBetweenClasses();
            startTime = DateUtils.getDate(DateUtils.formatStrDateHHmm(startTime), "HH:mm", 30, Calendar.MINUTE);
            appointmentTimeList.add(startTime);
        }
        return ResultInfo.success(appointmentTimeList);
    }
}
